package com.jams.goodox.utils;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.alipay.sdk.app.PayTask;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.jams.goodox.BaseActivity;
import com.jams.goodox.BuildConfig;
import com.jams.goodox.R;
import com.jams.goodox.SePref;
import com.jams.goodox.TownApplicationLike;
import com.jams.goodox.activity.wallet.SetPayPasswordActivity;
import com.jams.goodox.constant.Constants;
import com.jams.goodox.constant.UamaPayCode;
import com.jams.goodox.entity.MoneyPayResultInfo;
import com.jams.goodox.entity.WXEntity;
import com.jams.goodox.entity.pay.AiliPayBean;
import com.jams.goodox.entity.pay.BalancePayBean;
import com.jams.goodox.entity.pay.WeChatPayBean;
import com.jams.goodox.entity.resp.AliInfoResp;
import com.jams.goodox.listen.PayListener;
import com.jams.goodox.net.ProtocolManagers;
import com.jams.goodox.net.RetrofitCallbackListener;
import com.jams.goodox.net.RetrofitUnSuccessCallbackListener;
import com.jams.goodox.net.services.LifeService;
import com.jams.goodox.net.services.MineService;
import com.jams.goodox.net.services.ServiceService;
import com.jams.goodox.utils.alipay.PayUtils;
import com.jams.goodox.utils.alipay.Result;
import com.jams.goodox.widget.PromptBuilderDialog;
import com.jams.goodox.wxapi.MD5;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import retrofit2.Call;

/**
 * Created by jams on 2017/7/26.
 * ***
 * Tel: ***
 * <p>
 * 支付工具类
 */

public class UamaPayUtils {
    // 余额支付密码错误次数上限
    private final static int BALANCE_WRONG_COUNT = 5;


    /**
     * 余额支付
     * <p>
     * type       订单类型  1个人  2企业
     * userId     如果是企业，则传企业账户id,否则传null
     * balance    余额
     * orderId    订单id
     * paySubCode 如果是服务订单则传对应的服务id,否则传null
     */
    public static void payByBalance(final Activity context, final BalancePayBean balancePayBean, final PayListener payListener) {
        if (!(context instanceof BaseActivity)) {
            return;
        }
        switch (balancePayBean.getType()) {
            case 2://企业
                showPasswordDialog(context, balancePayBean, false, payListener);
                break;
            case 1://个人
                if (SePref.isSetPayPwd()) {
                    showPasswordDialog(context, balancePayBean, true, payListener);
                } else {
                    showSetPasswordDialog(context);
                }
            default:
                break;
        }

    }

    //请求余额支付接口
    private static void balancePayRequest(final Activity context, final BalancePayBean balancePayBean, String password, final PayListener payListener) {
        ProgressDialogUtils.show(context, "正在支付...");
        if (!(context instanceof BaseActivity)) {
            return;
        }
        ((BaseActivity) context).enqueue(((BaseActivity) context).createCallService(MineService.class).payByBalance(balancePayBean.getUserId(),
                balancePayBean.getBalance(), balancePayBean.getOrderId(), password, balancePayBean.getPaySubCode()), new RetrofitUnSuccessCallbackListener<MoneyPayResultInfo>() {
            @Override
            public void unSuccess(String status, String msg) {
                ProgressDialogUtils.dismiss();
                if (status.equals("106")) {
                    payListener.payResult(UamaPayCode.PAY_ERROR, msg);
                } else {
                    onError(msg);
                }
            }

            @Override
            public void onSuccess(Call<MoneyPayResultInfo> call, MoneyPayResultInfo result) {
                ProgressDialogUtils.dismiss();
                if (result == null || result.getData() == null) {
                    return;
                }
                switch (result.getData().getPayStatus()) {
                    case 1://密码错误
                        passwordWrong(context, balancePayBean, result, payListener);
                        payListener.payResult(UamaPayCode.PWD_ERROR, result.getData().getPasswordWrongMsg());
                        break;
                    case 2://余额变动
                        payListener.payResult(UamaPayCode.BALANCE_CHANGE, "订单支付失败，您的账户可能存在多人操作，导致余额变动，请重新支付。");
                        break;
                    case 4://支付成功
                        payListener.payResult(UamaPayCode.PAY_SUCCESS, result.getMsg());
                        break;
                }

            }

            @Override
            public void onError(String msg) {
                ProgressDialogUtils.dismiss();
                payListener.payResult(UamaPayCode.PAY_FAIL_BY_NET, msg);
                showTip(context, "支付失败");
            }
        });
    }

    //弹出数字密码输入框
    private static void showPasswordDialog(final Activity activity, final BalancePayBean balancePayBean, boolean showForgetPwd, final PayListener payListener) {
        MessageDialog.showPasswordDialog(activity, new MessageDialog.DialogPasswordCompletedListener() {
            @Override
            public void confirm(String password) {
                balancePayRequest(activity, balancePayBean, MD5Utils.md5(password), payListener);
            }

            @Override
            public void forgetPwd() {
                goSetPassword(activity);
            }
        }, showForgetPwd);
    }

    /**
     * 去设置密码弹窗
     */
    private static void showSetPasswordDialog(final Activity activity) {
        new MaterialDialog.Builder(activity).content("您尚未设置支付密码，请先去设置")
                .positiveText("去设置").onPositive(new MaterialDialog.SingleButtonCallback() {
            @Override
            public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                goSetPassword(activity);
            }
        }).negativeText("取消").onNegative(new MaterialDialog.SingleButtonCallback() {
            @Override
            public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                dialog.dismiss();
            }
        }).show();
    }

    //去设置密码
    private static void goSetPassword(Activity activity) {
        Intent i = new Intent(activity, SetPayPasswordActivity.class);
        Bundle b = new Bundle();
        i.putExtras(b);
        activity.startActivity(i);
    }

    /**
     * 支付结果密码错误
     */
    private static void passwordWrong(final Activity activity, final BalancePayBean balancePayBean, final MoneyPayResultInfo info, final PayListener payListener) {
        if (balancePayBean.getType() == 2) {//说明是企业服务，授权用户不可以找回企业密码
            new PromptBuilderDialog(activity)
                    .setContent(info.getData().getPasswordWrongMsg())
                    .setPositive(R.string.i_know)
                    .show();
            return;
        }
        String superText;
        String cancelText;
        if (info.getData().getPasswordWrongCount() == BALANCE_WRONG_COUNT) {
            superText = "找回密码";
            cancelText = "取消";
        } else {
            superText = "忘记密码";
            cancelText = "重新输入";
        }
        MessageDialog.showDoubleConfirmDialog(activity, "", info.getData().getPasswordWrongMsg(), superText, cancelText, new MessageDialog.DialogDoubleConfirmClickListener() {
            @Override
            public void confirm(int type) {
                if (type == 0) {  //左边按钮
                    if (info.getData().getPasswordWrongCount() != BALANCE_WRONG_COUNT) {
                        showPasswordDialog(activity, balancePayBean, true, payListener);
                    }
                } else if (type == 1) {  //右边按钮
                    goSetPassword(activity);
                }
            }
        });
    }


    /**
     * 支付宝支付
     *
     * @param ailiPayBean 支付宝请求对象
     * @param payListener 回调
     *                    <p>
     *                    "V33"是versionId,服务器加密使用
     */
    public static void payByAili(final Activity activity, final AiliPayBean ailiPayBean, final PayListener payListener) {
        if (!(activity instanceof BaseActivity)) {
            return;
        }
        ProgressDialogUtils.show(activity, "正在支付...");
        ((BaseActivity) activity).enqueue(((BaseActivity) activity).createCallService(LifeService.class).getAlipayInfo(ailiPayBean.getId(), ailiPayBean.getType(), "V33"), new RetrofitCallbackListener<AliInfoResp>() {
            @Override
            public void onSuccess(Call<AliInfoResp> call, AliInfoResp result) {
                AliInfoResp.DataBean infoBean = result.getData();
                try {
                    Constants.RSA_PRIVATE = AESOperator.getInstance().decrypt(infoBean.getRsaPrivate());
                    Constants.RSA_PUBLIC = infoBean.getRsaPuclic();
                    Constants.SELLER = AESOperator.getInstance().decrypt(infoBean.getSellerAccount());
                    Constants.PARTNER = AESOperator.getInstance().decrypt(infoBean.getPartnerId());
                    Constants.NOTIFY_URL = AESOperator.getInstance().decrypt(infoBean.getNotifyUrl());
                    goAliPay(activity, ailiPayBean.getMoneyCharge(), ailiPayBean.getCode(), ailiPayBean.getTitle(), payListener);
                } catch (Exception e) {
                    showTip(activity, "支付失败");
                    ProgressDialogUtils.dismiss();
                }
            }

            @Override
            public void onError(String msg) {
                showTip(activity, "支付失败");
                ProgressDialogUtils.dismiss();
            }
        });
    }

    /**
     * 前往阿里支付
     */
    private static void goAliPay(final Activity activity, String chargeMoney, String serialNumber, String title, final PayListener payListener) {
        String info = null;
        try {
            String orderInfo = PayUtils.getOrderInfo(title, title, chargeMoney, serialNumber);
            String sign = PayUtils.sign(orderInfo);
            sign = URLEncoder.encode(sign, "UTF-8");
            info = orderInfo + "&sign=" + "\"" + sign + "\"" + "&" + PayUtils.getSignType();
        } catch (UnsupportedEncodingException e) {
            ProgressDialogUtils.dismiss();
        }

        final String orderInfo = info;
        if (orderInfo == null) {
            ProgressDialogUtils.dismiss();
            return;
        }

        new Thread() {
            public void run() {
                PayTask aliPay = new PayTask(activity);
                String result = aliPay.pay(orderInfo);
                Result result2 = new Result(result);
                result2.parseResult();
                // 判断resultStatus 为“9000”则代表支付成功，具体状态码代表含义可参考接口文档
                if (TextUtils.equals(result2.resultStatus, "9000")) {
                    ProgressDialogUtils.dismiss();
                    payListener.payResult(UamaPayCode.PAY_SUCCESS, "支付成功");
                } else {
                    // 判断resultStatus 为非“9000”则代表可能支付失败 “8000”
                    // 代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认，最终交易是否成功以服务端异步通知为准（小概率状态）
                    if (TextUtils.equals(result2.resultStatus, "8000")) {
                        ProgressDialogUtils.dismiss();
                        payListener.payResult(UamaPayCode.PAY_WAIT, "支付失败");
                        showTip(activity, "支付失败");//之前是支付确认中 ，现在同意提示失败
                    } else if (TextUtils.equals(result2.resultStatus, "6001")) {
                        ProgressDialogUtils.dismiss();
                        payListener.payResult(UamaPayCode.PAY_CANCEL, "支付取消");
                        showTip(activity, "支付取消");
                    } else {
                        ProgressDialogUtils.dismiss();
                        payListener.payResult(UamaPayCode.PAY_ERROR, "支付失败");
                        showTip(activity, "支付失败");
                    }
                }
            }
        }.start();
        ProgressDialogUtils.dismiss();
    }


    //微信支付
    public static void payByWeChat(final Activity activity, final WeChatPayBean weChatPayBean) {
        ProgressDialogUtils.show(activity, "正在支付...");
        ((BaseActivity) activity).enqueue(((BaseActivity) activity).createCallService(ServiceService.class).getServiceWxPayId(weChatPayBean.getOrderId(), weChatPayBean.getPayType()),
                new RetrofitCallbackListener<WXEntity>() {
                    @Override
                    public void onSuccess(Call<WXEntity> call, final WXEntity wxentity) {
                        try {
                            if (wxentity != null) {
                                if (ProtocolManagers.SUCCESS.equals(wxentity.getStatus())) {
                                    WXEntity.WXResult data = wxentity.getData();
                                    if (data != null && !TextUtils.isEmpty(data.getMch_id()) &&
                                            !TextUtils.isEmpty(data.getPrepay_id())) {

                                        final IWXAPI msgapi = WXAPIFactory.createWXAPI(TownApplicationLike.getInstance(), null);
                                        // 将该app注册到微信
//                                msgapi.registerApp(Constant.WEIXIN_APPID);
                                        msgapi.registerApp(BuildConfig.WEIXIN_APPID);
                                        PayReq request = new PayReq();
//                                request.appId = Constant.WEIXIN_APPID;
                                        request.appId = BuildConfig.WEIXIN_APPID;
                                        request.partnerId = data.getMch_id();
                                        request.prepayId = data.getPrepay_id();
                                        request.packageValue = "Sign=WXPay";
                                        request.nonceStr = genNonceStr();
                                        request.timeStamp = String.valueOf(genTimeStamp());

                                        List<NameValuePair> signparams = new LinkedList<>();
                                        signparams.add(new BasicNameValuePair("appid", request.appId));
                                        signparams.add(new BasicNameValuePair("noncestr", request.nonceStr));
                                        signparams.add(new BasicNameValuePair("package", request.packageValue));
                                        signparams.add(new BasicNameValuePair("partnerid", request.partnerId));
                                        signparams.add(new BasicNameValuePair("prepayid", request.prepayId));
                                        signparams.add(new BasicNameValuePair("timestamp", request.timeStamp));

                                        request.sign = genAppSign(signparams);
                                        msgapi.sendReq(request);
                                        ProgressDialogUtils.dismiss();
                                    } else {
                                        ProgressDialogUtils.dismiss();
                                        showTip(activity, "支付失败");
                                    }

                                } else {
                                    ProgressDialogUtils.dismiss();
                                    showTip(activity, wxentity.getMsg());
                                }
                            } else {
                                ProgressDialogUtils.dismiss();
                            }

                        } catch (Exception e) {
                            ProgressDialogUtils.dismiss();
                        }
                    }

                    @Override
                    public void onError(String msg) {
                        ProgressDialogUtils.dismiss();
                    }
                });
    }

    public static void payWx( PayReq request){
            final IWXAPI msgapi = WXAPIFactory.createWXAPI(TownApplicationLike.getInstance(), null);
            // 将该app注册到微信
//                                msgapi.registerApp(Constant.WEIXIN_APPID);
            msgapi.registerApp(BuildConfig.WEIXIN_APPID);
            List<NameValuePair> signparams = new LinkedList<>();
            signparams.add(new BasicNameValuePair("appid", request.appId));
            signparams.add(new BasicNameValuePair("noncestr", request.nonceStr));
            signparams.add(new BasicNameValuePair("package", request.packageValue));
            signparams.add(new BasicNameValuePair("partnerid", request.partnerId));
            signparams.add(new BasicNameValuePair("prepayid", request.prepayId));
            signparams.add(new BasicNameValuePair("timestamp", request.timeStamp));

            request.sign = genAppSign(signparams);
            msgapi.sendReq(request);
    }

    private static String genNonceStr() {
        Random random = new Random();
        return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
    }

    private static long genTimeStamp() {
        return System.currentTimeMillis() / 1000;
    }

    private static String genAppSign(List<NameValuePair> params) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < params.size(); i++) {
            sb.append(params.get(i).getName());
            sb.append('=');
            sb.append(params.get(i).getValue());
            sb.append('&');
        }
        sb.append("key=");
        sb.append(BuildConfig.WX_APIKEY);
        try {
            return MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
        } catch (NullPointerException e) {
            return "";
        }
    }

    private static void showTip(Activity activity, final String msg) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ToastUtil.showShort(TownApplicationLike.getInstance(), msg);
            }
        });
    }
}
